/* eslint-disable no-undef */
let { app, BrowserWindow, ipcMain, dialog } = require('electron')
let path = require('path')
let createTray = require('./controller/tray')
const fs = require('fs')
const axios = require('axios')

//窗口调整
// eslint-disable-next-line no-undef
require('./controller/changeWindowSize')

let isChildWindowOpen = false
let childWindow = null
let createWindow = () => {
  let win = new BrowserWindow({
    width: 800,
    height: 700,
    minWidth: 400, // 设置最小宽度
    minHeight: 300, // 设置最小高度
    frame: false, // 去掉默认边框和标题栏
    titleBarStyle: 'hidden', // 隐藏标题栏
    autoHideMenuBar: true, // 自动隐藏菜单栏
    webPreferences: {
      preload: path.join(__dirname, './preload/index.js')
    }
  })

  // win.loadFile('index.html')

  // 下面的url为自己启动vite项目的url。
  win.loadURL('http://localhost:5173/')
  // 打开electron的开发者工具
  win.webContents.openDevTools({ mode: 'detach' })
  createTray(app, win)
}

// 创建子页面窗口
let createChildWindow = () => {
  if (isChildWindowOpen) {
    if (childWindow) {
      if (childWindow.isMinimized()) {
        childWindow.restore() // 恢复窗口（如果已最小化）
      }
      childWindow.focus()
    }
    return
  }
  childWindow = new BrowserWindow({
    width: 500,
    height: 600,
    minWidth: 400,
    minHeight: 350,
    frame: false,
    titleBarStyle: 'hidden',
    autoHideMenuBar: true,
    webPreferences: {
      preload: path.join(__dirname, './preload/index.js')
    }
  })

  isChildWindowOpen = true
  childWindow.loadURL('http://localhost:5173/child')
  childWindow.webContents.openDevTools({ mode: 'detach' })
  childWindow.on('closed', () => {
    isChildWindowOpen = false
    childWindow = null
  })
}

ipcMain.handle('sent-event', (event, params) => {
  console.log(params)
  if (isChildWindowOpen) {
    return true
  }
  return false
})

ipcMain.handle('open-select-path-dialog', async () => {
  const result = await dialog.showOpenDialog({
    properties: ['openDirectory']
  })
  return result
})

//下载文件

ipcMain.handle('download-file', (event, { fileUrl, outputFileName, outputFileAddress }) => {
  let outputLocationPath = path.join(outputFileAddress + '\\', outputFileName)

  let receivedBytes = 0
  let startTime = Date.now()
  let paused = false
  let resume = false
  let cancelTokenSource = null
  let downloadPromise = null
  let writer = null

  const sendProgress = (data) => {
    if (event.sender && !event.sender.isDestroyed()) {
      try {
        event.sender.send('download-progress', data)
      } catch (err) {
        console.error('Failed to send progress update:', err)
      }
    }
  }

  const cleanUp = () => {
    if (writer) {
      writer.close() // 确保写入流关闭
      writer = null
    }
    // 清理临时文件
    if (fs.existsSync(outputLocationPath)) {
      try {
        fs.unlinkSync(outputLocationPath)
        console.log('delete outputLocationPath')
        console.log(outputLocationPath)
      } catch (err) {
        console.error('删除已下载文件时出错:', err)
      }
    }
    // 重置状态
    receivedBytes = 0
    startTime = Date.now()
    paused = false
    resume = false
    cancelTokenSource = null
    downloadPromise = null
    writer = null
  }

  const downloadFile = async () => {
    if (!resume) {
      cancelTokenSource = axios.CancelToken.source()
    }

    if (resume) {
      // 如果是恢复下载，添加 Range 头部来继续下载
      downloadPromise = axios({
        method: 'get',
        url: fileUrl,
        responseType: 'stream',
        headers: { Range: `bytes=${receivedBytes}-` },
        cancelToken: cancelTokenSource.token
      })
    } else {
      downloadPromise = axios({
        method: 'get',
        url: fileUrl,
        responseType: 'stream',
        cancelToken: cancelTokenSource.token
      })
    }

    try {
      const response = await downloadPromise
      const totalBytes = parseInt(response.headers['content-length'], 10) + receivedBytes

      writer = fs.createWriteStream(outputLocationPath, { flags: 'a' })
      response.data.pipe(writer)

      response.data.on('data', (chunk) => {
        if (!paused) {
          receivedBytes += chunk.length
          const elapsedTime = (Date.now() - startTime) / 1000
          const downloadSpeed = receivedBytes / elapsedTime
          const remainingTime = (totalBytes - receivedBytes) / downloadSpeed
          const progress = Math.floor((receivedBytes / totalBytes) * 100)
          sendProgress({
            progress,
            speed: (downloadSpeed / 1024 / 1024).toFixed(2), // MB/s
            remainingTime: remainingTime.toFixed(2), // 秒
            receivedBytes: (receivedBytes / 1024 / 1024).toFixed(2), // MB
            totalBytes: (totalBytes / 1024 / 1024).toFixed(2) // MB
          })
        } else {
          // 暂停时停止写入数据
          writer.end()
        }
      })

      return new Promise((resolve, reject) => {
        writer.on('finish', () => {
          resolve(outputLocationPath)
        })
        writer.on('error', (err) => {
          // 删除文件时的错误处理
          cleanUp()
          reject(err)
        })
      })
    } catch (error) {
      if (axios.isCancel(error)) {
        console.log('下载已取消')
        // 清理文件
        cleanUp()
        return 'canceled'
      } else {
        throw error
      }
    }
  }

  // 取消下载的处理逻辑
  ipcMain.once('cancel-download', () => {
    if (cancelTokenSource) {
      cancelTokenSource.cancel('用户取消了下载')
    }
    cleanUp()
    // 向渲染进程发送下载已取消的消息
    if (event.sender && !event.sender.isDestroyed()) {
      try {
        event.sender.send('user-canceled', {
          message: '下载已取消',
          canceled: true,
          outputPath: outputLocationPath
        })
      } catch (err) {
        console.error('Failed to send cancellation message:', err)
      }
    }
  })

  ipcMain.on('pause-download', () => {
    paused = true
    if (writer) {
      writer.end()
    }
  })

  ipcMain.on('resume-download', () => {
    if (paused) {
      paused = false
      startTime = Date.now() // 重置开始时间，以便准确计算速度
      resume = true // 恢复下载
      downloadFile()
    }
    
  })
  cleanUp()
  return downloadFile()
})

ipcMain.on('open-child-window', () => {
  createChildWindow()
})

app.whenReady().then(() => {
  createWindow()
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})
